package cn.wdm.ymcc.rocketmq.consummer;

import cn.wdm.ymcc.domain.PayOrder;
import cn.wdm.ymcc.dto.PayDto;
import cn.wdm.ymcc.service.IPayOrderService;
import cn.wdm.ymcc.util.AssertUtil;
import com.alibaba.fastjson.JSONObject;
import org.apache.rocketmq.common.message.MessageExt;
import org.apache.rocketmq.spring.annotation.ConsumeMode;
import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
import org.apache.rocketmq.spring.core.RocketMQListener;
import org.apache.rocketmq.spring.core.RocketMQLocalTransactionListener;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.nio.charset.StandardCharsets;
import java.util.Date;

@Component
@RocketMQMessageListener(
        consumerGroup="courseOrderToPayTransaction",
        topic="courseOrder-topic",
        selectorExpression="courseOrder-tag"
        //messageModel = MessageModel.CLUSTERING  默认是集群模式，一个消息只会被一个消费者消费
)
/**
 * MessageExt 里面是要消费的消息Message PayDto
 */
public class OrderToPayConsummer implements RocketMQListener<MessageExt> {
    @Autowired
    private IPayOrderService iPayOrderService;
    /**
     * 消费订单的消息，生成支付单。
     * 保证消费的幂等性
     *
     * 扩展：作为RocketMq，消费方是否签收消息是通过是否有异常来判断的
     *      *    onMessage方法体：
     *      *      1.如果有异常，签收失败 -- 此消息会滞留在Mq中，下次还会再被消费--直到MQ 自动清理垃圾
     *      *      2.如果没有异常，签收成功  -- 消息就不再会被再次消费
     *  1.非空校验
     * 业务判断：
     *  2.根据订单号 查询支付单库中有没有该支付单
     *  2.1 有 说明已经消费过，没有签收，直接签收。
     *  2.2 没有，说明没有消费过，保存订单。
     * @param messageExt
     */
    @Override
    public void onMessage(MessageExt messageExt) {
        byte[] bytes = messageExt.getBody();
        AssertUtil.isNotNull(bytes,"消息体为空，拒绝签收消息");
        String msgStr = new String(bytes, StandardCharsets.UTF_8);
        PayDto payDto = JSONObject.parseObject(msgStr, PayDto.class);
        //1.根据订单号查询支付订单
        PayOrder payOrder=iPayOrderService.selectByOrderNo(payDto.getOrderNo());
        //1.1 支付订单不为空，说明消费过，直接签收
        if (payOrder != null) {
            System.out.println("你的订单已经消费过了，订单号为："+payOrder.getOrderNo());
            return;
        }
        //1.2 支付单位空，则生成新的支付单
        payOrder = new PayOrder();
        BeanUtils.copyProperties(payDto,payOrder);
        payOrder.setCreateTime(new Date());
        payOrder.setPayStatus(PayOrder.STATE_WAIT_PAY);
        iPayOrderService.insert(payOrder);
    }
}
